1. Field of the Invention
The present application relates generally to an improved data processing apparatus and method and more specifically to an apparatus and method for performing an efficient and self-balancing verification of multi-threaded microprocessors.
2. Background of the Invention
A microprocessor is the heart of a modern computer. A microprocessor is a chip made up of millions of transistors and other elements organized into specific functional operating units, including arithmetic units, cache memory and memory management, predictive logic and data movement.
Processors in modern computers have grown tremendously in performance, capabilities, and complexity over the past decade. One exemplary performance improvement in modern computers is the ability to multi-thread. Any computer program consists of many instructions for operating on data. Each of these instructions may be split into two or more simultaneously (or pseudo-simultaneously) running tasks or threads. Multithreading generally occurs by time-division multiplexing (“time slicing”) in very much the same way as the parallel execution of multiple tasks (computer multitasking): the processor switches between different threads. This context switching can happen so fast as to give the illusion of simultaneity to an end user. On a multiprocessor or multi-core system, threading can be achieved via multiprocessing, wherein different threads and processes can run literally simultaneously on different processors or cores.
In order to verify multi-threaded microprocessors, there are several problems which are difficult to solve, such as balancing the length of instruction streams, achieving a desired cross thread interaction, and efficient test generation. In order to balance the length of the instruction streams running on all threads such that they are roughly the same length so that in simulation or on real hardware, multiple instruction streams must be run for the majority of the test case. Creating such multiple instruction streams that are independent of one another is often a difficult task. While one approach might be to synchronize all of the threads prior to starting the test and at different points while running the tests by inserting synchronization routines into the test, the synchronization of all of the threads has a drawback though spending most of the test in the synchronization routines instead of the body of the test and therefore reduces the probability of finding design bugs.
The same holds true with trying to achieve the desired cross thread interactions. That is, lining up the instructions on one thread relative to instructions on another thread can also require spending most of the test in the lining up the instructions instead of the body of the test and therefore reduces the probability of finding design bugs. Under normal circumstances, for each additional thread that is part of the verification process the time required to generate an efficient test increases at least linearly. So, if a multi-threading test is being run on a simulator or real hardware, where the overhead of simulating additional threads does not increase at least linearly, then the time spent generating the test is growing faster (possibly significantly faster) than the simulation time. The net result is that test generation can become a bottleneck to the verification process.